<template>
  <a-modal
    :width="modalWidth"
    :title="formModel.type === 'edit' ? '编辑用户分群规则' : '创建用户分群'"
    :visible="formModel.visible"
    :confirm-loading="formModel.loading"
    :maskClosable="false"
    @ok="onSubmit"
    @cancel="onClose"
  >
    <a-form-model
      ref="groupingEditForm"
      :model="group"
      :rules="formRules"
      :label-col="{ span: 2 }"
      :wrapper-col="{ span: 22 }"
    >

      <a-form-model-item label="数据源" prop="datasourceId">
        <a-select
          v-model="group.datasourceId"
          show-search
          placeholder="请选择数据源"
          style="width:200px"
          :default-active-first-option="false"
          :show-arrow="true"
          :filter-option="false"
          :not-found-content="null"
          :option-label-prop="'label'"
          @change="changeDatasource"
          :disabled="editDisable"
        >
          <a-select-option v-for="item in datasourceList" :key="item.datasourceId" :label="item.datasourceName">
            {{ item.datasourceName }}
          </a-select-option>
        </a-select>
      </a-form-model-item>
      <a-divider></a-divider>
      <div v-if="!showRules">

      </div>
      <div v-else>
        <a-form-model-item label="分群名称" prop="name" >
          <a-input v-model="group.name" style="width: 300px"></a-input>
        </a-form-model-item>
        <a-form-model-item label="更新方式">
          <a-radio-group v-model="group.type">
            <a-radio :value=0>定时更新</a-radio>
            <a-radio :value=1>手动更新</a-radio>
          </a-radio-group>
        </a-form-model-item>
        <a-form-model-item label="自动导出" >
          <a-radio-group v-model="group.exportConfig.autoExport">
            <a-radio :value=0>关闭</a-radio>
            <a-radio :value=1>开启</a-radio>
          </a-radio-group>
        </a-form-model-item>

        <a-form-model-item v-if="group.exportConfig.autoExport === 1" label="导出字段">
          <a-row>
            <a-col span="12">
              <a-select mode="multiple" v-model="group.exportConfig.properties">
                <a-select-option v-for="item in this.exportProperties" :key="item.name" :label="item.name">{{ item.displayName }}</a-select-option>
              </a-select>
            </a-col>
          </a-row>
        </a-form-model-item>


        <a-form-model-item label="分群规则">
          <div class="rules-area">
            <div class="rules-condition">
              <span class="rules-split"></span>
              <div class="rules-condition-option">
                <a-button class="rules-condition-button" v-on:click="switchCondition">{{ group.config.condition === 'AND' ? '且' : '或' }}</a-button>
              </div>
            </div>
            <div class="rules-items">
              <span>用户属性符合: </span>
              <a-button v-on:click="addUserRule">添加属性</a-button>
              <MultiLevelFilter
                ref="userFilter"
                v-model="group.config.user_rule"
                v-bind:properties="userProperties"
                v-bind:datasourceId="group.datasourceId">
              </MultiLevelFilter>
              <span>用户行为符合: </span>
              <a-button v-on:click="addEventRule">添加事件</a-button>
              <UserActionGroup
                ref="actionGroup"
                v-bind:actions="group.config.event_rule"
                v-bind:properties="eventProperties"
                v-bind:events="events"
                v-bind:measures="measures"
                v-bind:datasourceId="group.datasourceId" >
              </UserActionGroup>
              <span>行为序列符合: </span>
              <a-button v-on:click="addActionSequence">添加序列</a-button>
              <UserActionSequenceGroup
                ref="actionSequenceGroup"
                v-bind:events="events"
                v-bind:properties="eventProperties"
                v-bind:sequences="group.config.actions_rule"
                v-bind:datasourceId="group.datasourceId"
              >
              </UserActionSequenceGroup>
            </div>
          </div>
        </a-form-model-item>
      </div>


    </a-form-model>
  </a-modal>
</template>

<script>
import MultiLevelFilter from "@/views/components/Filter/MultiLevelFilter";
import UserActionGroup from "@/views/userProfile/userGroup/components/UserActionGroup";
import UserActionSequenceGroup from "@/views/userProfile/userGroup/components/UserActionSequenceGroup";
import EventConfigUtil from "@/utils/EventConfigUtil";
import {mapActions} from "vuex";
import {addUserGroupApi, updateUserGroupApi} from "@/api/userGroup";

const formRules = {
  datasourceId: [
    {
      required: true,
      trigger: 'blur',
      message: '请选择项目'
    }
  ],
  name: [
    {
      max: 100,
      trigger: 'blur',
      message: '分群名称长度不能大于100个字符'
    }
  ],
};

export default {
  name: "groupingEditModal",
  components: { MultiLevelFilter, UserActionGroup, UserActionSequenceGroup},
  props: {
    formModel: Object,
    group: Object,
    datasourceList: Array,
  },
  data () {
    return {
      formRules,
      modalWidth: 1000,
      editDisable: false,
      eventProperties: [],
      userProperties: [],
      exportProperties: [],
      measures: [],
      events: [],
    }
  },
  watch:{
    group: function(val) {
      if (val && val.datasourceId){
        this.getRuleProperties(val.datasourceId)
        this.editDisable = true
      }else if (this.formModel.type !== 'add') {
        this.$message.error('参数获取异常，请刷新后重试');
      }
    },
    'formModel.visible': function (val) {
      if (!val){
        this.$refs.groupingEditForm.resetFields()
        this.events = []
        this.measures = []
        this.eventProperties = []
        this.userProperties = []
        this.exportProperties = []
      }
    }
  },
  computed:{
    showRules (){
      return this.eventProperties && this.eventProperties.length > 0 && this.userProperties && this.userProperties.length >0 &&
        this.exportProperties && this.exportProperties.length >0 && this.events.length >0 && this.measures && this.measures.length > 0
    }
  },
  methods: {
    ...mapActions('analyseType', [
      'getPropertiesEvent',
      'getPropertiesUser',
      'getMetaUserProperties',
      'getEvents',
      'getMeasures',
      'getPropertiesOfUserTag'
    ]),
    changeDatasource (id){
      this.getRuleProperties(id)
    },
    switchCondition: function() {
      if(this.group.config.condition === 'AND') {
        this.group.config.condition = 'OR';
      } else {
        this.group.config.condition = 'AND';
      }
    },
    getRuleProperties (datasourceId) {
      if (!datasourceId){
        return
      }
      this.getEvents(datasourceId).then(res=>{
        if (res && res.code === 0){
          this.events = [...res.data]
        }
      })
      this.getMeasures(datasourceId).then(res=>{
        if (res && res.code === 0){
          this.measures = [...res.data]
        }
      })
      this.getPropertiesEvent(datasourceId).then(res=>{
        if (res && res.code === 0){
          this.eventProperties = [...res.data]
        }
      })
      this.getPropertiesUser(datasourceId).then(res=>{
        this.userProperties = this.userProperties.concat(res.data);
      })
      this.getPropertiesOfUserTag(datasourceId).then(res=>{
        this.userProperties = this.userProperties.concat(res.data.data);
      }).catch(err => {
        this.$message.error('获取用户标签数据失败，原因：' + err)
        console.error(err)
      })
      this.getMetaUserProperties(datasourceId).then(res=>{
        this.exportProperties = [...res]
      })
    },
    addUserRule (){
      this.$refs.userFilter.addRule();
    },
    addEventRule (){
      this.$refs.actionGroup.addItem();
    },
    addActionSequence (){
      this.$refs.actionSequenceGroup.addItem();
    },
    onSubmit (){
      if (this.formModel.type === 'add'){
        this.createUserGroup()
      }else {
        this.updateUserGroup()
      }
    },
    createUserGroup: function () {
      this.formModel.loading = true
      if (!this.validateRule()) {
        this.formModel.loading = false
        return
      }
      const body = {
        datasourceId:this.group.datasourceId,
        name: this.group.name,
        type: parseInt(this.group.type),
        config: JSON.stringify( EventConfigUtil.deleteKey(this.group.config)),
        exportConfig: JSON.stringify(this.group.exportConfig)
      }
      addUserGroupApi(body).then(res => {
        if (res && res.code === 0) {
          this.$emit("loadUserGroups");
          this.formModel.visible = false
          this.$message.success('用户分群创建成功')
        }else {
          this.$message.error('用户分群创建失败，原因：' + res.msg)
        }
      }).catch(error => {
        console.error(error);
        this.$message.error('用户分群创建失败，原因：' + error)
      }).finally(() => {
        this.formModel.loading = false
      })
    },
    updateUserGroup: function () {
      this.formModel.loading = true
      if (!this.validateRule()) {
        this.formModel.loading = false
        return
      }
      const body = {
        name: this.group.name,
        type: parseInt(this.group.type),
        config: JSON.stringify( EventConfigUtil.deleteKey(this.group.config)),
        exportConfig: JSON.stringify(this.group.exportConfig)
      }
      updateUserGroupApi(this.group.id,body).then(res => {
        if (res && res.code === 0) {
          this.$emit("loadUserGroups");
          this.formModel.visible = false
          this.$message.success('用户分群更新成功')
        }else {
          this.$message.error('用户分群更新失败，原因：' + res.msg)
        }
      }).catch(error => {
        console.error(error);
        this.$message.error('用户分群更新失败，原因：' + error)
      }).finally(() => {
        this.formModel.loading = false
      })
    },
    validateRule:function () {
      if (typeof this.group.name !== "string" || this.group.name.length < 1){
        this.$message.error('分群名称不能为空');
        return false
      }
      if ( this.group.config.user_rule.rules.length === 0
        && this.group.config.event_rule.rules.length === 0
        && this.group.config.actions_rule.rules.length === 0){
        this.$message.error('用户属性、用户行为或行为序列至少需要设置一项');
        return false;
      }
      return this.validateUserRule() && this.validateEventRule() && this.validateActionSequenceRule() && this.validateAutoExportRule();
    },
    validateUserRule: function() {
      for(let i = 0; i < this.group.config.user_rule.rules.length; i++) {
        if ( this.group.config.user_rule.rules[i].operator.indexOf("is") !== 0
          && ((this.group.config.user_rule.rules[i].value === '' || this.group.config.user_rule.rules[i].value === null)
            && this.group.config.user_rule.rules[i].values.length === 0)) {
          this.$message.error('用户属性值不能为空');
          return false;
        }
      }
      return true;
    },
    validateEventRule: function () {
      for (let i = 0; i < this.group.config.event_rule.rules.length; i++) {
        let eventRule = this.group.config.event_rule.rules[i];
        if (eventRule.time.type === 'relative_time') {
          if (eventRule.time.values.length !== 1) {
            this.$message.error('用户行为规则相对时间设置不正确');
            return false;
          } else {
            let tokens = eventRule.time.values[0].split(',');
            if (tokens[0] < tokens[1]) {
              this.$message.error('用户行为规则相对时间范围设置不正确');
              return false;
            }
          }
        } else if (eventRule.time.type === 'absolute_time') {
          if (eventRule.time.values.length !== 2) {
            this.$message.error('用户行为规则固定时间设置不正确');
            return false;
          }
        }
        if (eventRule.values.length === 2 && eventRule.values[0] > eventRule.values[1]) {
          this.$message.error('用户行为规则起始值不能大于结束值');
          return false;
        }
        for(let j = 0; j < eventRule.filter.rules.length; j++) {
          if (eventRule.filter.rules[j].operator.indexOf("is") !== 0
            && ((eventRule.filter.rules[j].value === '' || eventRule.filter.rules[j].value === null)
              && eventRule.filter.rules[j].values.length === 0)) {
            this.$message.error('筛选条件值不能为空');
            return false;
          }
        }
      }
      return true;
    },
    validateActionSequenceRule (){
      for (let i in this.group.config.actions_rule.rules){
        let asr = this.group.config.actions_rule.rules[i]
        if (asr.time.type === 'relative_time') {
          if (asr.time.values.length !== 1) {
            this.$message.error('行为序列规则相对时间设置不正确');
            return false;
          } else {
            let tokens = asr.time.values[0].split(',');
            if (tokens[0] < tokens[1]) {
              this.$message.error('行为序列规则相对时间范围设置不正确');
              return false;
            }
          }
        } else if (asr.time.type === 'absolute_time') {
          if (asr.time.values.length !== 2) {
            this.$message.error('行为序列规则固定时间设置不正确');
            return false;
          }
        }
        let actions = asr.actions
        if (!actions|| actions.length < 2){
          this.$message.error("行为序列最少配置两项");
          return false;
        }else {
          for (let j in actions){
            let action = actions[j]
            if (!action.event || action.event.length<1){
              this.$message.error("行为序列事件参数配置不正确，请验证后重试！");
              return false;
            }
          }
        }
      }
      return true
    },
    validateAutoExportRule (){
      if (this.group.exportConfig.autoExport === 0){
        return true
      }
      if (this.group.exportConfig.exportType === "CSV"){
        if (typeof this.group.exportConfig.properties !== 'object' || this.group.exportConfig.properties.length < 1){
          this.$message.error("自动导出字段不能为空");
          return false;
        }
      }
      return true
    },
    onClose (){
      this.formModel.visible = false
    },

  }
}
</script>

<style scoped>
.rules-area {
  display: flex;
  justify-content: flex-start;
  width: 100%;
}
.rules-condition {
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  padding: 5px 5px;
}

.rules-condition .rules-split {
  display: inline-block;
  width: 2px;
  background: #2d8cf0;
  height: 100%;
  position: relative;
  left: 17px;
}

.rules-condition .rules-condition-option {
  position: relative;
  z-index: 9;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-direction: column;
  border-radius: 2px;
}
.rules-condition-button {
  cursor: pointer;
  padding: 4px 8px;
  border: 1px solid rgb(200, 200, 200);
  background-color: rgb(245, 245, 245);
  border-radius: 3px;
}
.rules-items {
  flex: 1;
}
</style>
